# -*- coding: utf-8 -*-

import re
import os

commentPat = r'^[ \t\r\f\v]*?#.*?\n'
blankPat = r'^\s*?\n'

class Counter(object):
    'Istanziare fornendo il codice sorgente di un programma python'
     
    def __init__(self, source, verbose=False):
        self.verbose = verbose
        self.source = source
        self.run()
    
    def __repr__(self):
        res = ''
        res += '\nn° commenti       : %s' % self.nComment
        res += '\nn° linee vuote    : %s' % self.nBlank
        res += '\nn° linee di codice: %s' % self.nCode
        res += '\nn° linee totali   : %s' % self.nTotalLines
        res += '\n'
        return res

    def run(self):
        nTotalLines = len(self.source.splitlines())
        comments = re.findall(commentPat, self.source, re.MULTILINE)
        blankLines = re.findall(blankPat, self.source, re.MULTILINE)
        
        # debug
        self.comments = comments
        self.blankLines = blankLines
        
        nCommentLines = len(comments)
        nBlankLines = len(blankLines)
        nCodeLines = nTotalLines - nCommentLines - nBlankLines
        
        # questo è l'output
        self.nComment = nCommentLines
        self.nBlank = nBlankLines
        self.nCode = nCodeLines
        self.nTotalLines = nTotalLines
        
        if self.verbose:
            print self

def count_file(path, verbose=False):
    'Restituisce una tripla costituita da: (nCode, nComment, nTot)'
    f = file(path)
    source = f.read()
    f.close()
    counter = Counter(source, verbose=verbose)
    return counter.nCode, counter.nComment, counter.nTotalLines

def count_directory(dirpath, verbose=False):
    'Restituisce una quadrupla: (nCodeTot, nCommentTot, nTotTot, nPyFiles)'
    nCodeTot, nCommentTot, nTotTot = 0, 0, 0
    filenames = os.listdir(dirpath)
    nPyFiles = 0
    for fn in filenames:
        if fn.endswith('.py'):
            fpath = os.path.join(dirpath, fn)
            if verbose:
                print fn
            nCode, nComment, nTot = count_file(fpath, verbose=verbose)
            nCodeTot += nCode
            nCommentTot += nComment
            nTotTot += nTot
            nPyFiles += 1
    return nCodeTot, nCommentTot, nTotTot, nPyFiles

def demo():
    f = file('pycodemeter.py')
    source = f.read()
    f.close()
    counter = Counter(source)
    print 'Linee vuote', counter.blankLines
    print 'Commenti:', counter.comments

if __name__ == '__main__':
    verbose = True
    import sys
    path = sys.argv[1]
    if os.path.isfile(path):
        print count_file(path, verbose=verbose)
    elif os.path.isdir(path):
        print count_directory(path, verbose=verbose)
